package com.why.simpleboot.core.core.entity;

import com.why.simpleboot.core.common.utils.UrlUtils;
import com.why.simpleboot.core.core.factory.RouterFactory;
import io.netty.handler.codec.http.HttpMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * @program: why-simpleboot-framework
 * @description:
 * @author: @why
 * @create: 2021-05-23 19:07
 **/
public class CreateMethodDefinitionFactory {
    private static final Logger logger = LoggerFactory.getLogger(CreateMethodDefinitionFactory.class);

    /**
     * 根据请求类型 封装不同的
     * @param method
     * @param url
     * @return
     */
    public static MethodDefinition getMethodDefinition(HttpMethod method, String url) {
        MethodDefinition methodDefinition = null;
        if (method == HttpMethod.GET) {
            methodDefinition = handle(url, RouterFactory.GET_MAPPING_MAP, RouterFactory.GET_URL_MAP);
        } else if (method == HttpMethod.POST) {
            methodDefinition = handle(url, RouterFactory.POST_MAPPING_MAP, RouterFactory.POST_URL_MAP);
        }
        // TODO: 2021/7/2  more  handler

        return methodDefinition;

    }

    /**
     * @param url:客户端发送过来的url地址，注意是已经剔除附带参数的url，eg；/user/why/?name=1 不可以。
     * @param requestMethodMappings：url所能调用的方法
     * @param urlMappings：正则url---》原url
     * @return
     */
    private static MethodDefinition handle(String url,
                                           Map<String, Method> requestMethodMappings,
                                           Map<String, String> urlMappings) {
        MethodDefinition methodDefinition = new MethodDefinition();
//        遍历整个map，因为map中key保存的是正则形式的url地址，所以我们要挨个进行匹配
//        eg: ^/user/name/?$ find /user/name/ --->true
        for (Map.Entry<String, Method> entry : requestMethodMappings.entrySet()) {
//            尝试匹配和当前url进行匹配
            Pattern pattern = Pattern.compile(entry.getKey());
            boolean flag = pattern.matcher(url).find();
//            匹配成功，设置要执行的方法
            if (flag) {
                methodDefinition.setMethod(entry.getValue());
                // 获得正则url对应的源目标地址
                String srcUrl = urlMappings.get(entry.getKey());
//                根据正则url和源url生成一个map对象
//                eg:请求url: name/why   源url name/{nick} --->生成 name=name  name=nick,最后交给解析器去处理
                Map<String, String> urlParameterMappings = UrlUtils.getUrlParameterMappings(url, srcUrl);
                methodDefinition.setPathVariableParameterMappings(urlParameterMappings);
                return methodDefinition;
            }
        }
        logger.warn("无法处理该请求参数。。。");
        return null;
    }
}
